package com.simplesoftwares.client.library.appstructure;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.libservice.GenricService;
import com.simplesoftwares.client.library.libservice.GenricServiceAsync;

/**
 * This class is super class of all tables.It Handles 
 * functionality common to all tables such that applying selection handler
 * setting dataproviders,pagers,keyproviders.
 * 
 * Class operates in two modes local mode where dataprovider is list or in server mode where data provider is
 * async.
 * 
 * To Do: The logic of async mode is never tested and used , make that perfect.
 * ,
 * @author Kamala
 *
 * @param <T> Entity type of this table
 */
 public abstract class SuperTable<T> extends ViewContainer {
	/**
	 * Underlying datagrid 
	 */
	protected DataGrid<T> table;
	/**
	 * List data provider for this grid.
	 */
	private ListDataProvider<T> listDataProvider;
	/**
	 * Async data provider for this data grid
	 */
	protected AsyncDataProvider<T> asyncDataProvider;
	/**
	 * Object of selection model,it provides the row click form fill functionality.
	 */
	protected TableSelection<T> selectionModel;
	/**
	 * Key provider object
	 * To Do: I dont know what the fuck this guy do, will understand.
	 */
	protected ProvidesKey<T> keyProvider;
	/**
	 * ArrayList for the list data provider
	 */
	protected ArrayList<T> dataproviderlist;
	/**
	 * Default pager size
	 * To Do : Never worked will have to see why.
	 */
	protected int DEFAULT_PAGER_SIZE=50;
	/**
	 * Pager size which can be set from outside.
	 */
	protected int PAGER_SIZE;
	/**
	 * Defaualt row coungt
	 */
	protected int DEFAULT_ROWCOUNT=40;
	/**
	 * Default height
	 */
	private String DEFAULTHEIGHT="150px";

    /**
     * Ui screen associated with this table.It means that when we will click on table row
     * Logic of selection handler will kick in and fill the screen with clicked object.
     */
	protected UiScreen<T> view;
	
	/**
	 * Handles Sorting of Columns
	 */
	protected ListHandler<T> columnSort;
	
	
	protected final GenricServiceAsync generivservice=GWT.create(GenricService.class);
	public SuperTable()
	{
		super();
		table = new DataGrid<T>();
		connectToLocal();
		createTable();
	
		initializekeyprovider();
		table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		content.add(table);
		table.setWidth("100%");
		setHeight(DEFAULTHEIGHT);
		table.setRowCount(DEFAULT_ROWCOUNT);
	}
	/**
	 * if underlying data provider is set in this way , it means that DataGrid will operate in live mode
	 * and will be connected to database.
	 * To Do: Not implemented urgently implement
	 * @param querry the querry object which will decide retrived data.
	 */
	
	public void connectToDb(MyQuerry querry)
	{
		createAsyncDataProvider(querry);
		
	}
	/**
	 * If underlying data provider is set in this way , it means that DataGrid will operate on local mode
	 * 
	 * To Do:Ideally listdataprovider should be set with the dataproviderlist variable . Do it in near future.
	 */
	public void connectToLocal()
	{
		
		if(table!=null && getListDataProvider()!=null)
		    getListDataProvider().removeDataDisplay(table);	
		setListDataProvider(new ListDataProvider<T>());
		dataproviderlist= new ArrayList<T>();
		getListDataProvider().addDataDisplay(table);
		addColumnSorting();
	}
	
	public void addColumnSorting() {
		// TODO Auto-generated method stub
		
	}
	/**
	 * If superTable is constructed in this way then on click of row view with get filled with clicked object
	 * @param mv The view coupled with this table.
	 * @author Kamala
	 */
	public SuperTable(UiScreen<T> mv)
	{
		this();
		view=mv;
		applySelectionModle();
		
	}
	/**
	 * Concrete implementation of this method adds columns on datagrid
	 */
	
	public abstract void createTable();
	
	
	
	/**
	 * Applies selection model to table.
	 */
	public void applySelectionModle()
	{
		selectionModel = new TableSelection<T>(view,keyProvider);
		table.setSelectionModel(selectionModel);
		
	}
	
	
	/**
	 * concrete implementation provides key provider object
	 */
	protected abstract void initializekeyprovider();
	
	public void createGui()
	{
		
		
	}
	public abstract void addFieldUpdater();

	public ListDataProvider<T> getDataprovider() {
		return getListDataProvider();
	}

	public void setDataprovider(ListDataProvider<T> dataprovider) {
		this.setListDataProvider(dataprovider);
	}

	public DataGrid<T> getTable() {
		return table;
	}

	public void setTable(DataGrid<T> table) {
		this.table = table;
	}

	public TableSelection<T> getSelectionModel() {
		return selectionModel;
	}

	public void setSelectionModel(TableSelection<T> selectionModel) {
		
		this.selectionModel=selectionModel;
		table.setSelectionModel(selectionModel);
	}

	public ProvidesKey<T> getKeyProvider() {
		return keyProvider;
	}

	public void setKeyProvider(ProvidesKey<T> keyProvider) {
		this.keyProvider = keyProvider;
	}

	

	public ArrayList<T> getDataproviderlist() {
		return dataproviderlist;
	}

	public void setDataproviderlist(ArrayList<T> dataproviderlist) {
		this.dataproviderlist = dataproviderlist;
	}
	
	
	public ViewContainer getView() {
		return view;
	}

	public void setView(UiScreen<T> view) {
		this.view = view;
	}
	
	/**
	 * Applies the simple pager on datagrid with passed page size.
	 * @param pagesize the size of applied pager
	 * @author Kamala
	 */
	 public void addPager(int pagesize)
	  {
		  this.PAGER_SIZE=pagesize;
		 
		  new SimplePager().setDisplay(table);
		  table.setPageSize(PAGER_SIZE);
		  Window.enableScrolling(false);
	  }
	 /**
	  * stub method not implemented.
	  * @param querry
	  */
	 
	 public void createAsyncDataProvider(MyQuerry querry)
	 {
		
		
	 }
	 /**
	  * Sets the height of datagrid with passed value
	  * @param height height of datagrid 
	  * To Do:May be we should give an applyStyle method to this class also, with a default style.
	  * 
	  */
	 
	 protected void setHeight(String height)
	 {
		 table.setHeight(height);
	 }

	 /**
	  * stub implementation of validate in table.
	  * @return true if table is validated.False if table is not validated
	  */
	 public boolean validate() {
		
		return true;
	}
	
	
	 /**
	  * clears the datagrid.
	  * To Do: Please think logic of clear when data back up is async
	  */
	public void clear()
	{
		connectToLocal();
	}
	
	/**
	 * Make datagrid editable or uneditable.
	 * @param state true if editable false if uneditable
	 * To DO: Try to write concrete implementation at superclass level
	 */

	public abstract void  setEnable(boolean state);

	public ListDataProvider<T> getListDataProvider() {
		return listDataProvider;
	}

	public void setListDataProvider(ListDataProvider<T> listDataProvider) {
		this.listDataProvider = listDataProvider;
	}

	public void setValue(List<T>list)
	{
		if(this.getDataprovider()!=null && list!=null)
			getDataprovider().setList(list);
	}
	
	public List<T> getValue()
	{
		if(this.getDataprovider()!=null)
			return getDataprovider().getList();
		
		return null;
	}
	
	
}
